﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Messaging;
using System.Net;
#if !CLIENT
using System.Web.Configuration;
#endif

namespace TeamFoundation.EventBus
{
    /// <summary>
    /// Represents common utilities.
    /// </summary>
    public static class Utilities
    {
        /// <summary>
        /// The root namespace.
        /// </summary>
        public const string CoreNamespace = "urn:tfeb";

        /// <summary>
        /// The event data namespace.
        /// </summary>
        public const string EventNamespace = CoreNamespace + "/event";

        /// <summary>
        /// The subscription namespace.
        /// </summary>
        public const string SubscriptionNamespace = ManagerNamespace + "/subscription";

        /// <summary>
        /// The manager namespace.
        /// </summary>
        public const string ManagerNamespace = CoreNamespace + "/manager";

        /// <summary>
        /// Creates a message queue.
        /// </summary>
        /// <param name="queuePath">The queue path.</param>
        public static void CreateMessageQueue(string queuePath)
        {
            // Normalize.
            queuePath = ToServerPath(queuePath);
            if (!MessageQueue.Exists(queuePath))
            {
                using (var q = MessageQueue.Create(queuePath, true))
                {
                    // This is not default.
                    q.SetPermissions("Administrators", MessageQueueAccessRights.FullControl);
                }
            }
        }

        /// <summary>
        /// Normalizes a queue path into a queue path that can be
        /// used on a server.
        /// </summary>
        /// <param name="original">The original client or server path.</param>
        /// <returns>A normalized server queue path.</returns>
        public static string ToServerPath(string original)
        {
            if (original == null) return null;

            string look = Environment.MachineName.ToLowerInvariant() + "\\";
            if (original.ToLowerInvariant().StartsWith(look))
            {
                return ".\\" + original.Substring(look.Length);
            }

            look = Dns.GetHostName().ToLowerInvariant() + "\\";
            if (original.ToLowerInvariant().StartsWith(look))
            {
                return ".\\" + original.Substring(look.Length);
            }

            return original;
        }

        /// <summary>
        /// Normalizes a queue path into a queue path that can be
        /// used on a client.
        /// </summary>
        /// <param name="original">The original client or server path.</param>
        /// <returns>A normalized client queue path.</returns>
        public static string ToClientPath(string original)
        {
            if (original == null) return null;

            string look = ".\\";
            if (original.ToLowerInvariant().StartsWith(look))
            {
                return Dns.GetHostName() + "\\" + original.Substring(look.Length);
            }
            return original;
        }

#if !CLIENT
        /// <summary>
        /// Discovers the root URL to the application.
        /// </summary>
        /// <param name="request">The HTTP request.</param>
        /// <returns>The root URL.</returns>
        public static Uri DiscoverRootUrl(HttpRequest request)
        {
            string apPath = request.ApplicationPath;
            if (!apPath.EndsWith("/"))
                apPath += "/";
            Uri applicationPath = new Uri(apPath, UriKind.Relative);
            Uri url = request.Url;
            applicationPath = new Uri(url, applicationPath);
            return applicationPath;
        }

        /// <summary>
        /// Gets the list of supported event.
        /// </summary>
        /// <returns>The list of supported events.</returns>
        public static string[] GetEvents()
        {
            string c = WebConfigurationManager.AppSettings["events"];
            if (c == null)
                c = "";
            return c.Split(',');
        }
#endif
    }
}
